/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
/*
 * catchit
 * Copyright (C) 2013 Ryan Grinkewitz <graphite@Toto>
 * 
 */

#include "jumper.h"
#include "physics-manager.h"
#include "game-state-manager.h"


Jumper::Jumper(){
	xPosition = 0;
	yPosition = 0;
	xVelocity = 0;
	yVelocity = 0;
	collisionBox = new SDL_Rect();
	collisionBox->x = 0;
	collisionBox->y = 0;
	collisionBox->w = JUMPER_DIAMETER;
	collisionBox->h = JUMPER_DIAMETER;

	isOnPlatform = true;
	isWinner = false;

	level = 0;
	highestLevelReached = 0;
	score = 0;
}

Jumper::~Jumper(){
	delete collisionBox;
}

void Jumper::processTestAction(Action action){


	switch(action){
		case DO_NOTHING:
			break;
		case MOVE_LEFT:
			xVelocity -= JUMPER_DIAMETER/2;
			break;
		case MOVE_RIGHT:
			xVelocity += JUMPER_DIAMETER/2;
			break;
		case MOVE_UP:
			yVelocity -= JUMPER_DIAMETER/2;				
			break;
		case MOVE_DOWN:
			yVelocity += JUMPER_DIAMETER/2;
			break;
		case END_MOVE_LEFT:
			xVelocity += JUMPER_DIAMETER/2;
			break;
		case END_MOVE_RIGHT:
			xVelocity -= JUMPER_DIAMETER/2;
			break;
		case END_MOVE_UP:
			yVelocity += JUMPER_DIAMETER/2;
			break;
		case END_MOVE_DOWN:
			yVelocity -= JUMPER_DIAMETER/2;
			break;
	};


	PhysicsManager* physicsManager = PhysicsManager::getInstance();
	GameStateManager* gameStateManager = GameStateManager::getInstance();
	std::vector<Level*> levels = gameStateManager->getGameState ()->getLevels ();



    //Move the square left or right		
	xPosition += xVelocity;
	collisionBox->x = xPosition + SPRITE_X_OFFSET;

	//If the square went too far to the left or right or has collided with the wall
	if( ( xPosition < 0 ) || ( xPosition + JUMPER_DIAMETER > SCREEN_WIDTH ) ||
	   ( physicsManager->checkCollision( this,  levels) ) )
	{
	    //Move back
  		  xPosition -= xVelocity;
		collisionBox->x = xPosition + SPRITE_X_OFFSET;
	}
	

	//Move the square up or down
	yPosition += yVelocity;
	collisionBox->y = yPosition + SPRITE_Y_OFFSET;
	//If the square went too far up or down or has collided with the wall
	if( ( yPosition < 0 ) || ( yPosition + JUMPER_DIAMETER > SCREEN_HEIGHT ) || 
	   ( physicsManager->checkCollision( this, levels ) ) )
	{
		//Move back
		yPosition -= yVelocity;
		collisionBox->y = yPosition + SPRITE_Y_OFFSET;
	}
}


void Jumper::setXPosition(int xPosition){
	this->xPosition = xPosition;
	collisionBox->x = xPosition + SPRITE_X_OFFSET;
}

int Jumper::getXPosition(){
	return xPosition;
}

void Jumper::setYPosition(int yPosition){
	this->yPosition = yPosition;
	collisionBox->y = yPosition + SPRITE_Y_OFFSET;
}

int Jumper::getYPosition(){
	return yPosition;
}

void Jumper::setXVelocity(float xVelocity){
	this->xVelocity = xVelocity;
}

float Jumper::getXVelocity(){
	return xVelocity;
}

void Jumper::setYVelocity(float yVelocity){
	this->yVelocity = yVelocity;
}

float Jumper::getYVelocity(){
	return yVelocity;
}


void Jumper::setSpriteId(int spriteId){
	this->spriteId = spriteId;
}

int Jumper::getSpriteId(){
	return spriteId;
}

SDL_Rect* Jumper::getCollisionBox(){
	return collisionBox;
}

void Jumper::setCollisionBox(SDL_Rect* collisionBox){
	this->collisionBox = collisionBox;
}

void Jumper::setLevel(int level){
	this->level = level;
	if(level > highestLevelReached){
		highestLevelReached = level;
		score += 100;
	}
}

int Jumper::getLevel(){
	return level;
}

void Jumper::setPlatform(int platform){
	this->platform = platform;
}

int Jumper::getPlatform(){
	return platform;
}

void Jumper::processAction(Action action){
	PhysicsManager* physicsManager = PhysicsManager::getInstance();
	GameStateManager* gameStateManager = GameStateManager::getInstance();
	
	if(isOnPlatform)
	{
		switch(action){
			case JUMP_UP:
				yVelocity -= PLAYER_VELOCITY;
//				xPosition += xVelocity;
//				collisionBox->x = xPosition + SPRITE_X_OFFSET;

				yPosition += yVelocity;
				collisionBox->y = yPosition + SPRITE_Y_OFFSET;

				isOnPlatform = false;
				physicsManager->setCurrentTime (SDL_GetTicks ());
				break;
			case JUMP_LEFT:
				xVelocity -= PLAYER_VELOCITY;
				yVelocity -= PLAYER_VELOCITY;
				xPosition += xVelocity;
				collisionBox->x = xPosition + SPRITE_X_OFFSET;

				yPosition += yVelocity;
				collisionBox->y = yPosition + SPRITE_Y_OFFSET;

				isOnPlatform = false;
				physicsManager->setCurrentTime (SDL_GetTicks ());
				break;
			case JUMP_RIGHT:
				xVelocity += PLAYER_VELOCITY;
				yVelocity -= PLAYER_VELOCITY;
				xPosition += xVelocity;
				collisionBox->x = xPosition + SPRITE_X_OFFSET;

				yPosition += yVelocity;
				collisionBox->y = yPosition + SPRITE_Y_OFFSET;

				isOnPlatform = false;
				physicsManager->setCurrentTime (SDL_GetTicks ());
				break;
	
		};
	

		

	}else{
		//Adjust for gravity
		std::vector<Level*> levels = gameStateManager->getGameState ()->getLevels ();

		//Move the square left or right		
		xPosition += xVelocity;
		collisionBox->x = xPosition + SPRITE_X_OFFSET;
	
		float elapsedTime = (SDL_GetTicks () - physicsManager->getCurrentTime ())/1000.0;
		yVelocity += (GRAVITY_ACCELERATION * elapsedTime);
		if (yVelocity > MAX_VELOCITY){
			yVelocity = MAX_VELOCITY;
		}		
		//std::cout << "********************"<< std::endl;
		//std::cout << "elapsedTime = " << elapsedTime << std::endl;
		//std::cout << "yVelocity = " << yVelocity << std::endl;
		

		
		yPosition += yVelocity;
		collisionBox->y = yPosition + SPRITE_Y_OFFSET;

		//If landed on platform
		while(/*( yPosition + JUMPER_DIAMETER > SCREEN_HEIGHT ) 
		      ||*/ ( (yVelocity >= 0) && ( physicsManager->checkCollision( this, levels ) )) )
		{
		    //Move back
		    yPosition--;
			collisionBox->y = yPosition + SPRITE_Y_OFFSET;
			isOnPlatform = true;
			setPlatform (physicsManager->getLastPlatform ());
			setLevel(physicsManager->getLastLevel());
			yVelocity = xVelocity = 0;
		}	

		//TBD: this should scroll screen rather than cap the player
		//only applies to player, not computer
		if (yPosition < 0 && getIsPlayer()){
			yPosition-=yVelocity;
		}

		//Bounce off walls
		if((xPosition + SPRITE_X_OFFSET) < 0 ||
		   ((xPosition + JUMPER_DIAMETER + SPRITE_X_OFFSET) > SCREEN_WIDTH)){
			xVelocity = -xVelocity;
		}
		
		while((xPosition + SPRITE_X_OFFSET) < 0){
			xPosition++;
		}

		while((xPosition + JUMPER_DIAMETER + SPRITE_X_OFFSET) > SCREEN_WIDTH){
			xPosition--;
		}
	}
}